#include "exact_arithmetics.h"
#include <vector>

bool reversed_comparing (double i, double j)
{
   return (i > j);
}

void add_mul_to_vector(std::vector<double> & v, double a, double b, int sign)
{
   std::pair<double,double> temp_pair;
   temp_pair = mul(a,b);

   v.push_back(sign * temp_pair.first);

   v.push_back(sign * temp_pair.second);
}

void fill(std::vector<double>& v, const vect& a, const point& b)
{
   add_mul_to_vector(v, a.b.x, b.y, 1);
   add_mul_to_vector(v, a.b.x, a.a.y, -1);
   add_mul_to_vector(v, a.a.x, b.y, -1);
   add_mul_to_vector(v, a.b.y, b.x, -1);
   add_mul_to_vector(v, a.b.y, a.a.x, 1);
   add_mul_to_vector(v, a.a.y, b.x, 1);
}

void initialize_vectors(const std::vector<double>& v, std::vector<double>& v1, std::vector<double>& v2)
{
   size_t v_size = v.size();

   for (size_t i = 0; i < v_size; ++i)
   {
      if (v[i] > 0)
      {
         v1.push_back(v[i]);
      } else
      {
         v2.push_back(v[i]);
      }
   }
}

double sum_vector(const std::vector<double>& v)
{
   double result = 0;
   size_t size = v.size();

   for (size_t i = 0; i < size; ++i)
   {
      result += v[i];
   }

   return result;
}

int sum_heaps(std::vector<double>& v)
{
   /*std::vector<double> v_positive,v_negative;

   initialize_vectors(v,v_positive,v_negative);

   std::make_heap(v_positive.begin(),v_positive.end());
   std::make_heap(v_negative.begin(),v_negative.end(),reversed_comparing);

   while (!(v_positive.empty() || (v_negative.empty()))) {
      std::pop_heap(v_positive.begin(),v_positive.end());
      std::pop_heap(v_negative.begin(),v_negative.end(),reversed_comparing);

      double dbl1 = v_positive.back(), dbl2 = v_negative.back();

      v_positive.pop_back();
      v_negative.pop_back();

      if (dbl1 != -dbl2)
      {

         if (dbl1 > -2 * ((int) v_negative.size()) * dbl2)
         {
            return 1;
         }

         if (-dbl2 > 2 * ((int) v_positive.size()) * dbl1)
         {
            return -1;
         }

         //int exp1 = exponent(dbl1), exp2 = exponent(dbl2);
         //if (exp1 == exp2)
         //{

         //   if (dbl1 > -dbl2)
         //   {
         //      v_positive.push_back(dbl1 + dbl2);
         //      std::push_heap(v_positive.begin(),v_positive.end());
         //   } else
         //   {
         //      v_negative.push_back(dbl1 + dbl2);
         //      std::push_heap(v_negative.begin(),v_negative.end(),reversed_comparing);
         //   }

         //} else
         //{
         //   if (exp1 > exp2) //So, dbl1 > temp > -dbl2
         //   {
         //      double temp = (double) (2LL << exp2);

         //      v_positive.push_back(dbl1 - temp);
         //      std::push_heap(v_positive.begin(),v_positive.end());

         //      v_positive.push_back(temp + dbl2);
         //      std::push_heap(v_positive.begin(),v_positive.end());
         //   } else
         //   {                //-dbl2 > temp > dbl1
         //      double temp = (double) (2LL << exp1);

         //      v_negative.push_back(dbl1 - temp);
         //      std::push_heap(v_negative.begin(),v_negative.end(),reversed_comparing);

         //      v_negative.push_back(temp + dbl2);
         //      std::push_heap(v_negative.begin(),v_negative.end(),reversed_comparing);
         //   }
         //}

         std::pair<double,double> current_sum = sum(dbl1,dbl2);

         if (current_sum.first > 0)
         {
            v_positive.push_back(current_sum.first);
            std::push_heap(v_positive.begin(),v_positive.end());
         } else
         {
            if (current_sum.first < 0)
            {
               v_negative.push_back(current_sum.first);
               std::push_heap(v_negative.begin(),v_negative.end(),reversed_comparing);
            }
         }

         if (current_sum.second > 0)
         {
            v_positive.push_back(current_sum.second);
            std::push_heap(v_positive.begin(),v_positive.end());
         } else
         {
            if (current_sum.second < 0)
            {
               v_negative.push_back(current_sum.second);
               std::push_heap(v_negative.begin(),v_negative.end(),reversed_comparing);
            }
         }
      }
   }

   int vps = v_positive.size(), vns = v_negative.size();

   if (vps - vns != 0)
   {
      return ((vps - vns) / std::abs((int) (vps - vns)));
   } else
   {
      return 0;
   }*/
   return 0;
}

void sum_with_roundoffs(std::vector<double>& v, double dbl, int begin)
{
   std::vector<double> temp;

   for (size_t i = begin; i < v.size(); ++i)
   {
      std::pair<double,double> current_sum = sum(v[i], dbl);
      temp.push_back(current_sum.second); dbl = current_sum.first;
   }
   temp.push_back(dbl);

   v = temp;
}